package com.gzsj.genealogyManagement.people.service.impl;


import com.aspose.words.*;
import com.gzsj.common.core.config.AppConfig;
import com.gzsj.common.utils.AsposeUtils;
import com.gzsj.common.utils.directory.DirectoryUtils;
import com.gzsj.genealogyManagement.people.domin.CreateTable;
import com.gzsj.genealogyManagement.people.domin.People;
import com.gzsj.genealogyManagement.people.domin.Table;
import com.gzsj.genealogyManagement.people.mapper.PeopleMapper;
import com.gzsj.genealogyManagement.people.service.PeopleService;
import com.gzsj.genealogyManagement.people.utils.NumberToChinese;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.ByteArrayInputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.List;


@Service
public class PeopleServiceImpl implements PeopleService {


    @Autowired
    private PeopleMapper peopleMapper;




    /**
     * html转Docx文档
     * @throws Exception
     */
    @Override
    public void exportDocx() throws Exception {
        AsposeUtils.crackAspose();

        List<CreateTable> createTableList = peopleMapper.findExportList();

        if(createTableList!=null && !createTableList.isEmpty()){
            for (CreateTable createTable : createTableList) {


                createTable.setStatus("1");
                // 文档生成成功、修改对应状态，保存文件下载地址
                peopleMapper.updateCreateTable(createTable);

                People people = new People();
                people.setId(createTable.getPeopleId());
                people.setTableId(createTable.getTableId());
                people.setType(createTable.getType());
                people.setStart(createTable.getStart());
                people.setEnd(createTable.getEnd());
                people.setStartPage(createTable.getStartPage());
                // 0横版  1竖版
                String headHtmlString = getHtmlHeader(people.getType());
                // HTML 字符串
                //  整理每个第一代、以及当前第一代对应的其他子代，子代对应的其他孙子代
                List<People> peopleGenerationList = getPeopleGenerationList(people);

                List<People> allPeoples = new ArrayList<>();
                //  数据整理成指定的格式
                collectAndPrintPeoples(peopleGenerationList, allPeoples);

                // 拼接页面内容
                StringBuilder contentHtmlString = new StringBuilder();
                contentHtmlString.append(headHtmlString);
                contentHtmlString.append(processPeople(allPeoples,people.getType(),people));
                contentHtmlString.append(getHtmlFoot());

                // 将 HTML 字符串转换为 ByteArrayInputStream
                ByteArrayInputStream inputStream = new ByteArrayInputStream(contentHtmlString.toString().getBytes(StandardCharsets.UTF_8));

                Document doc = new Document(inputStream);
                DocumentBuilder builder = new DocumentBuilder(doc);

                // 移动到页眉
                builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY);

                // 设置段落格式
                builder.getParagraphFormat().setAlignment(ParagraphAlignment.LEFT);

                // 设置制表位，确保右侧内容对齐到页面右边
                double pageWidth = builder.getPageSetup().getPageWidth() - builder.getPageSetup().getLeftMargin() - builder.getPageSetup().getRightMargin();
                TabStopCollection tabStops = builder.getParagraphFormat().getTabStops();
                tabStops.clear();
                tabStops.add(new TabStop(pageWidth, TabAlignment.RIGHT, TabAlignment.LEFT));


                // 查询标题以及堂号
                Table tableInfo = peopleMapper.findTitleAndHallName(people.getTableId());

                if(tableInfo != null){
                    builder.getFont().setName("宋体(正文)"); // 设置字体为宋体
                    builder.getFont().setSize(12); // 设置字体大小为12磅
                    // 写入左侧内容并添加制表符
                    builder.write(tableInfo.getTitle()+"\t");
                    // 写入右侧内容，它将对齐到页面的右边
                    builder.write(tableInfo.getHall());

                    builder.writeln(); // 确保下一行开始新的段落
                }

                // 添加实线
                Shape line = new Shape(doc, ShapeType.LINE);
                line.setWidth(pageWidth);  // 线的宽度设置为页面宽度减去边距
                line.setStrokeWeight(1.5); // 线的粗细
                builder.insertNode(line);


                // 设置起始页码为 5
                Section section = builder.getCurrentSection();
                section.getPageSetup().setRestartPageNumbering(true);
                section.getPageSetup().setPageStartingNumber(Integer.parseInt(people.getStartPage()));

                // 移动到页脚
                builder.moveToHeaderFooter(HeaderFooterType.FOOTER_PRIMARY);
                builder.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER);

                // 插入页码字段
                builder.insertField("PAGE", "");

                String fileName = createTable.getTitle()+"(" +createTable.getStart()+"-"+createTable.getEnd()+")"+"世" + ("0".equals(people.getType()) ? "【横版】" : "【竖版】") + ".docx";

                String filePath = DirectoryUtils.createTodayDateDirectory() + "/"  + fileName ;

                // 保存为 DOCX 文件
                doc.save(filePath, SaveFormat.DOCX);

                String downloadUrl = AppConfig.getAccessIp()  + "/download/document?filePath=" + filePath;
                createTable.setStatus("2");
                createTable.setUrl(downloadUrl);
                // 文档生成成功、修改对应状态，保存文件下载地址
                peopleMapper.updateCreateTable(createTable);

            }

        }


    }

    /**
     *
     * @param allPeoples
     * @param type 族谱类型
     * @return
     */
    private String processPeople(List<People> allPeoples,String type,People p1) {
        StringBuilder contentHtmlString = new StringBuilder();

        if(allPeoples!=null && !allPeoples.isEmpty()){

            // 排行
            int maleRanking = 0;
            int famaleRanking = 0;
            // 辈分
            String  generationalPosition = "0";
            // 辈分
            String sameGeneration = "0";

            String lastTimeparentName = "";

            // 是否跳过循环
            boolean isSkip = true;
            for (People people : allPeoples) {




                // 出嫁的美女不进行展示

                if("1".equals(people.getMarry())){
                    continue;
                }

                // 如果是配偶作为子内容、否则作为主内容显示
                if("1".equals(people.getIsSpouse())){
                    continue;
                }

                // 获取辈分
                String level = people.getLevel();

                if (level == null || level.isEmpty()) {
                    break;
                }

                if(!(generationalPosition.equals(level))){
                    // 重置排行
                    maleRanking = 0;
                    famaleRanking = 0;
                    generationalPosition = level;
                }

                // level第一代始祖
                String title = "1".equals(generationalPosition) ? "始祖" : "";

                // 除第一代、当前代的第几子
                // 儿子女儿分开算
                String currentRanking = "";

                // 上级名称
                String parentName = people.getParentName();

                // 如果是同一个父亲、则排名自增、父亲不同则清0
                if(!lastTimeparentName.equals(parentName)){
                    lastTimeparentName = parentName;
                    maleRanking = 0;
                    famaleRanking = 0;

                }
                if(!"1".equals(generationalPosition)){

                    // 当前子女排行
                    String gender = people.getGender();
                    if("1".equals(gender)){
                        maleRanking++;

                        currentRanking = determineRanking(maleRanking, true);

                    }else if("0".equals(gender)){
                        famaleRanking++;

                        currentRanking = determineRanking(maleRanking, false);
                    }

                }


                // 横版竖版rankStarInfo信息不同、则进行不同处理
                String rankStarInfo = "";
                String star = "1".equals(people.getStar())?"名流":"";
                if("1".equals(type)){

                    String  rankInfo = title + parentName + currentRanking;
                    rankInfo = "".equals(rankInfo)?"":"&nbsp;" +rankInfo+"&nbsp;" ;
                    rankStarInfo =  rankInfo + ("".equals(star)?"":"&nbsp;" +star+"&nbsp;");
                }else{
                    title = "".equals(title)?"":"【"+title+"】";
                    String rankInfo = parentName + currentRanking;
                    rankInfo = title +  ("".equals(rankInfo)?"":"【"+rankInfo+"】");
                    rankStarInfo = rankInfo + ("".equals(star)?"": "【"+star+"】");
                }


                String id = p1.getId();
                String start = p1.getStart();
                String end = p1.getEnd();
                // 依据id开始，输出所有的辈份以及排行
                if(id.equals(people.getId())){
                    isSkip = false;
                }
                if(isSkip){
                    continue;
                }

                // 将字符串转换为整数
                int startGeneration = Integer.parseInt(start);
                int endGeneration = Integer.parseInt(end);
                int  curGeneration = Integer.parseInt(end);
                if(curGeneration < startGeneration ){
                    continue;
                }

                if(curGeneration > endGeneration){
                   break;
                }




                String titleHtmlString ="";
                String segmentation = "0".equals(type) ? "<div  class=\"dotted_line\">\n" +
                        "             <span class=\"centered-text \">-------------------------------------------------</span>\n" +
                        "        </div>":"<div  class=\"dotted_line\">\n" +
                        "             <span class=\"centered-text \">▏ ▏ ▏ ▏ ▏ ▏ ▏ ▏ ▏ ▏ ▏ ▏ ▏ ▏ ▏ ▏ ▏ ▏ ▏ ▏ ▏ ▏ ▏ ▏ ▏ ▏ ▏ ▏ ▏ ▏ ▏ ▏ ▏ ▏</span>\n" +
                        "        </div>";

                titleHtmlString += segmentation;

                // 同一辈份主标题只展示一次
                if(!(sameGeneration.equals(generationalPosition))){
                    titleHtmlString +=
                            "         <div class=\"title\" style=\"\">\n" +
                                    "\n" +
                                    "            <span class=\"centered-text titleFontStyle\">"+"第"+NumberToChinese.numberToChinese(Integer.parseInt(level))+"世"+"</span>\n" +
                                    "         </div>\n";
                    titleHtmlString += segmentation;
                    sameGeneration = generationalPosition;
                }




                String roomPath = "0".equals(type)? horizontalVersionFormatString(people.getRoomPath()) : verticalPlateFormatString(people.getRoomPath());
                String clique = "";
                String village = people.getVillage();
                if("0".equals(type)){

                    clique  =  (village!=null?village:"")+("".equals(roomPath)?"":"&nbsp;-&nbsp;")+roomPath;
                }else{

                     clique  =   (village!=null?village:"")+("".equals(roomPath)?"":"&nbsp;&nbsp;|&nbsp;&nbsp;")+roomPath;
                }

                clique = clique != null ?clique:"";


                titleHtmlString +=
                        "\n" +
                                "         <div class=\"subTitle\" >\n" +
                                "            <span class=\"centered-text subTitleFontStyle\">"+clique+"</span>\n" +
                                "         </div>";

                titleHtmlString +="".equals(clique)?"":segmentation;

                titleHtmlString +=
                        "         <div class=\"content\">\n" +
                                "            <span class=\"name\">"+people.getName()+"</span>"+"<span class=\"rankStarInfo\">"+rankStarInfo+"</span>"+removePTags(people.getBiography())+"\n" +
                                "        </div>" +
                                "\n" ;



                //  1、通过我的id去匹配supose_id、查出所有的配偶id、
                List<People> mateList = optimizeLookup(allPeoples, "spouseId", "id",people.getId());


                String  mateHtmlString = "";
                if(mateList!=null && !mateList.isEmpty()){

                    for (People p : mateList) {

                        String isStar = "1".equals(p.getStar())?"名流":"";

                        if(!("".equals(isStar))){
                            isStar = "0".equals(type)?"【"+isStar+"】":"&nbsp;"+isStar+ " &nbsp;";
                        }

                        // 当前记录有几个儿女
                        String son = "";
                        String daughter = "";
                        int sonNum = 0;
                        int daughterNum = 0;

                        //  依据配偶id匹配对应的parentid查询出子女的数量
                        List<People> childList = optimizeLookup(allPeoples, "parentSpouseId", "id",p.getId());

                        String with = "0".equals(type)?"【配】":"配&nbsp";
                        if(childList!=null && !childList.isEmpty()){
                            for (People children : childList) {


                                if("1".equals(children.getGender())){
                                    son += children.getName() + " ";
                                    sonNum++;
                                }else if("0".equals(children.getGender())){
                                    daughter += children.getName() + " ";
                                    daughterNum++;
                                }
                            }

                            // 依据子女的个数、拼接相应的字符串
                            String childInfo = "";
                            if(sonNum>0 && daughterNum>0){
                                childInfo += "子"+NumberToChinese.numberToChinese(sonNum)+"：<span style=\"font-weight: bolder\">"+son+"</span>" + "女"+NumberToChinese.numberToChinese(daughterNum)+"：<span style=\"font-weight: bolder\">"+daughter+"</span>\n";
                            }else if(sonNum>0){
                                childInfo += "子"+NumberToChinese.numberToChinese(sonNum)+"：<span style=\"font-weight: bolder\">"+son+"</span>\n";
                            }else if(daughterNum>0){
                                childInfo += "女"+NumberToChinese.numberToChinese(daughterNum)+"：<span style=\"font-weight: bolder\">"+daughter+"</span>\n";
                            }


                            mateHtmlString +=
                                    "         <div class=\"content\">\n" +
                                            "             <span class=\"mate\" >"+with+""+p.getName()+"</span> <span class=\"isStar\">"+isStar+"</span> "+removePTags(p.getBiography())+ childInfo +
                                            "        </div>\n";
                        }else{
                            mateHtmlString +=
                                    "         <div class=\"content\">\n" +
                                            "             <span class=\"mate\">"+with+""+p.getName()+"</span> <span class=\"isStar\">"+isStar+"</span> "+removePTags(p.getBiography()) +
                                            "        </div>\n";
                        }






                    }

                }

                contentHtmlString.append(titleHtmlString);
                contentHtmlString.append(mateHtmlString);


            }

        }



        return contentHtmlString.toString();
    }

    // 判断是第几个儿子或子女
    private String determineRanking(int ranking, boolean isMale) {
        if (ranking == 1) {
            return isMale ? "长子" : "长女";
        } else if (ranking == 2) {
            return isMale ? "次子" : "次女";
        } else if (ranking == 3) {
            return isMale ? "之子" : "之女";
        } else {
            return "第" + NumberToChinese.numberToChinese(ranking) + (isMale ? "子" : "女");
        }
    }


    private String getHtmlFoot(){
         return "</span>\n" +
                 "\n" +
                 "    </div>\n" +
                 "\n" +
                 "</div>\n" +
                 "</body>\n" +
                 "</html>\n";
    }

    private String getHtmlHeader(String type) {
        // 垂直排列
        String contentContainerDiv  = "0".equals(type)?"height: 720px;":
                "height: 720px;\nwriting-mode: vertical-rl;\n text-orientation: upright;\n";

        String contentContainer = "0".equals(type)?"display: flex;\nflex-wrap: wrap;\n":
                "display: flex;\nflex-wrap: wrap;\nflex-direction: row-reverse;\n";


        String titleSubTitle = " text-align: center;\nfont-family: 'SimSun', 'serif';\nfont-size: 26pt;\n";

        String contentFontStyleAndDiv = "0".equals(type)?" line-height: 38px;":
                " line-height: 32px\n";



        String name ="font-family: 'SimSun', 'serif';\nfont-size: 23.6px;\nfont-weight: bolder;\n";




        String rankStarInfo = "font-family: 'SimSun', 'serif';\nfont-size: 18.7px;\nfont-weight: bolder\n";

        String content = "0".equals(type)?"font-family: 'SimSun', 'serif';\nfont-size: 18.7px; /* 四号字体大小 */\nletter-spacing: 2px;":
                "font-family: 'SimSun', 'serif';\nfont-size: 18.7px; /* 四号字体大小 */\nletter-spacing: 2px;\n";

        String mate = "0".equals(type)?"font-family: 'SimSun', 'serif'\n; font-weight: bolder;\n":
                "font-family: 'SimHei', '黑体';\n font-size: 18.7px;font-weight: bolder\n";

        String isStar = "0".equals(type)?"font-family: 'SimSun', 'serif'\n; font-weight: bolder;\n":
                " font-family: 'SimHei', '黑体'\n; font-size: 14.7px;\n";


         return "<!DOCTYPE html>\n" +
                 "<html lang=\"zh\">\n" +
                 "<head>\n" +
                 "    <meta charset=\"UTF-8\">\n" +
                 "    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n" +
                 "    <title>罗塘村第一世</title>\n" +
                 "    <style>\n" +
                 "\n" +
                 "        .modal-body{\n" +
                 "            display: grid;\n" +
                 "            justify-items: center\n" +
                 "        }\n" +
                 "\n" +
                 "        .contentContainer div {\n" +
                 "\n" +
                            contentContainerDiv+
                 "        }\n" +
                 "\n" +
                 "        .centered-text {\n" +
                 "            position: absolute;\n" +
                 "            top: 50%;\n" +
                 "            left: 50%;\n" +
                 "            transform: translate(-50%, -50%);/* 将元素在其父容器中居中对齐。这行代码的作用是在两个方向（水平和垂直）上移动元素，以确保它完全居中于其父元素。*/\n" +
                 "            color: #000;\n" +
                 "        }\n" +
                 "\n" +
                 "        .titleFontStyle, .subTitleFontStyle {\n" +

                 "            text-align: center;\n" +
                 "        }\n" +
                 "\n" +
                 "        .contentContainer{\n" +
                            contentContainer +
                 "\n" +
                 "        }\n" +
                 "\n" +
                 "        .mainContainer {\n" +
                 "            width: 595px;\n" +
                 "        }\n" +
                 "\n" +
                 "        .title,.subTitle {\n" +
                            titleSubTitle+
                 "        }\n" +
                 "\n" +
                 "        .content {\n" +
                             content+
                 "        }" +
                 "\n" +
                 "        .contentFontStyle div {\n" +
                            contentFontStyleAndDiv +
                 "        }\n" +
                 "\n" +
                 "        .name {\n" +
                            name +
                 "        }\n" +
                 "\n" +
                 "        .dotted_line {\n" +
                 "            text-align: center;\n" +
                 "            font-family: 'SimSun', 'serif';\n" +
                 "            font-size: 14.2pt;\n" +
                 "            font-weight: lighter;!important;\n" +
                 "            margin-left:14px;\n" +
                 "        }\n" +
                 "\n" +
                 "        .rankStarInfo {\n" +
                            rankStarInfo+
                 "        }\n" +
                 "\n" +
                 "        .mate {\n" +
                            mate+
                 "        }\n" +
                 "        .isStar {\n" +
                            isStar+
                 "        }\n" +
                 "\n" +
                 "\n" +
                 "    </style>\n" +
                 "</head>\n" +
                 "<body>\n" +
                 "\n" +
                 "<div class=\"modal-body\">\n" +
                 "\n" +
                 "    <div class=\"mainContainer\" >\n" +
                 "    <span class=\"contentContainer contentFontStyle\"   >\n" +
                 "\n";
    }


    // 快速排序
    public List<People>  optimizeLookup(List<People> allPeoples, String parentIdField, String idField,String id) {
        Map<String, List<People>> parentMap = new HashMap<>();


        try {
            // 填充映射
            for (People person : allPeoples) {
                String parentId = getFieldValue(person, parentIdField);
                parentMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(person);
            }

            List<People> childrens = parentMap.get(id);
            return  childrens;

        } catch (IllegalAccessException | NoSuchFieldException e) {
            e.printStackTrace();
        }

        return null;
    }

    private String getFieldValue(People person, String fieldName) throws NoSuchFieldException, IllegalAccessException {
        Field field = person.getClass().getDeclaredField(fieldName);
        field.setAccessible(true);
        return (String) field.get(person);
    }


    // 过滤p标签
    private String removePTags(String text) {
        if (text == null) return null;
        // Regular expression to remove all <p> and </p> tags
        return text.replaceAll("</?p>", "");
    }


    // 专门用于打印和收集分类的方法
    private void collectAndPrintPeoples(List<People> peoples, List<People> allPeoples) {
        Collections.sort(peoples);  // 确保当前层级分类按sort排序
        List<People> allChildren = new ArrayList<>();

        for (People people : peoples) {

            allPeoples.add(people);   // 收集分类

            allChildren.addAll(people.getChildren());  // 收集所有子分类
        }

        if (allChildren!=null && !allChildren.isEmpty()) {
            collectAndPrintPeoples(allChildren, allPeoples);
        }
    }



    /**
     * 整理每个第一代、以及当前第一代对应的其他子代，子代对应的其他孙子代
     * @return
     */
    public  List<People> getPeopleGenerationList(People people){
        List<People> byPeopleList = peopleMapper.findByPeopleList(people);
        List<People>  fistGenerationList= new ArrayList<>();

        if(!byPeopleList.isEmpty()){
            for (People p : byPeopleList) {

                if("0".equals(p.getParentId())){


                    People rootPeople = isNextGeneration(byPeopleList, p.getId());
                    fistGenerationList.add(rootPeople);

                }
            }
        }
        return fistGenerationList;
    }




    // 获取每一代的下一代
    public static People isNextGeneration(List<People> byPeopleList, String rootId) {
        People root = findPeopleItemById(byPeopleList, rootId);
        if (root == null) {
            return null;
        }
        for (People item : byPeopleList) {

            if (item.getParentId().equals(root.getId())) {
                People child = isNextGeneration(byPeopleList, item.getId());
                root.addChild(child);
            }
        }
        return root;
    }

    private static People findPeopleItemById(List<People> items, String id) {
        for (People item : items) {
            if (id.equals(item.getId())) {
                return item;
            }
        }
        return null;
    }




    /**
     * 去掉字符串前后的连字符，并将中间的连字符替换为竖线
     * @param input 原始字符串
     * @return 转换后的字符串
     */
    public static String horizontalVersionFormatString(String input) {
        // 去掉前后的连字符
        String trimmedString = input.replaceAll("^-+|-+$", "");
        return trimmedString.replace("-", "&nbsp;-&nbsp;");
    }


    /**
     * 去掉字符串前后的连字符，并将中间的连字符替换为竖线
     * @param input 原始字符串
     * @return 转换后的字符串
     */
    public static String verticalPlateFormatString(String input) {
        // 去掉前后的连字符
        String trimmedString = input.replaceAll("^-+|-+$", "");
        // 替换中间的连字符为竖线
        return trimmedString.replace("-", "&nbsp;&nbsp;|&nbsp;&nbsp;");
    }





}



